package com.qrxl.common.service.impl;

import com.qrxl.common.exception.CustomException;
import com.qrxl.common.service.IFileStoreService;
import com.qrxl.commond.LocalFileCondition;
import com.qrxl.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * 本地文件存储
 *
 * @author zhoukun
 */
@Service
// @Configuration
@Conditional(LocalFileCondition.class)
public class LocalFileStoreServiceImpl extends AbstractFileStoreServiceImpl implements IFileStoreService {

    @Value("${custom.fileDir:/data/files}")
    String UPLOAD_PATH_PREFIX;

    @Override
    public String getMD5String(String path) {
        ByteArrayInputStream inputStream = new ByteArrayInputStream(realGetFileBytes(path));
        try {
            return MD5Util.getFileMD5StringByInputStream(inputStream).toUpperCase();
        } catch (IOException e) {
            throw new CustomException("获取md5失败", e);
        }
    }

    @Override
    public byte[] realGetFileBytes(String path) {
        if (StringUtils.isEmpty(path)) {
            return new byte[0];
        }
        path = UPLOAD_PATH_PREFIX + path;
        File file = new File(path);
        //文件不存在
        if (!file.exists()) {
            return new byte[0];
        }
        try {
            return fileToByte(file);
        } catch (Exception e) {
            throw new CustomException("获取字节失败", e);
        }
    }

    @Override
    public void writeData(HttpServletResponse response, String path) throws IOException {
        path = checkKey(path);
        path = UPLOAD_PATH_PREFIX + path;
        File file = new File(path);
        //文件不存在
        if (!file.exists()) {
            try (OutputStream outputStream = response.getOutputStream();) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.setContentType("text/html;charset=utf-8");
                outputStream.write("文件不存在".getBytes("utf-8"));
                outputStream.flush();
            }
        } else {
            String fileName = getFileNameFromUrl(path);
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "utf-8"));
            byte[] temp = new byte[1024];
            try (OutputStream outputStream = response.getOutputStream();
                 InputStream inputStream = new FileInputStream(file)) {
                response.setContentLength((int) file.length());
                int n;
                while ((n = inputStream.read(temp)) != -1) {
                    outputStream.write(temp, 0, n);
                    outputStream.flush();
                }
            }
        }
    }

    /**
     * 本地文件存储
     */
    @Override
    protected String uploadFileBytes(String key, byte[] bytes) throws IOException {
        String asbPath = UPLOAD_PATH_PREFIX + key;
        File file = new File(asbPath);
        if (!file.getParentFile().exists()) {
            //并发上传多张，如果目录不存在会出现问题
            synchronized (LocalFileStoreServiceImpl.class) {
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
            }
        }
        try (InputStream input = new ByteArrayInputStream(bytes);
             FileOutputStream fos = new FileOutputStream(file)) {
            int readLen;
            byte[] buff = new byte[10240];
            while ((readLen = input.read(buff)) != -1) {
                fos.write(buff, 0, readLen);
            }
        }
        //开发环境，图片上传到test环境
        return key;
    }

    @Override
    public boolean fileExist(String key) {
        String asbPath = UPLOAD_PATH_PREFIX + super.PATH_SPLIT + key;
        File file = new File(asbPath);
        return file.exists();
    }

    /**
     * desc: 通过url获取文件名
     */
    public static String getFileNameFromUrl(String url) {
        String name = new Long(System.currentTimeMillis()).toString() + ".X";
        int index = url.lastIndexOf("/");
        if (index > 0) {
            name = url.substring(index + 1);
            if (name.trim().length() > 0) {
                return name;
            }
        }
        return name;
    }
}
